package com.kang.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kang.base.LoginDataBase;
import com.kang.entity.SysMenu;
import com.kang.entity.SysUser;
import com.kang.mapper.SysMenuMapper;
import com.kang.mapper.SysUserMapper;
import com.kang.service.WeixinApiService;
import com.kang.util.*;
import com.kang.vo.RouterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class WeixinApiServiceImpl implements WeixinApiService {


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public Map<String, Object> genQrConnect() throws UnsupportedEncodingException {
        String redirectUri = URLEncoder.encode(ConstantPropertiesUtil.WX_REDIRECT_UURL, "UTF-8");
        Map<String, Object> map = new HashMap<>();
        map.put("appid", ConstantPropertiesUtil.WX_OPEN_APPID);
        map.put("redirect_uri", redirectUri);
        map.put("scope", "snsapi_login");
        map.put("state", System.currentTimeMillis()+"");//System.currentTimeMillis()+""
        return map;
    }

    @Override
    public void callback(String code, String state) {
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,
                ConstantPropertiesUtil.WX_OPEN_APPID,
                ConstantPropertiesUtil.WX_OPEN_APP_SECRET,
                code);
        //使用httpclient请求这个地址
        try {
            String accesstokenInfo = HttpClientUtils.get(accessTokenUrl);
            System.out.println("accesstokenInfo:"+accesstokenInfo);
            //从返回字符串获取两个值 openid 和 access_token
            JSONObject jsonObject = JSONObject.parseObject(accesstokenInfo);
            String openid = jsonObject.getString("openid");


            QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
            wrapper.eq("open_id",openid);
            SysUser user = sysUserMapper.selectOne(wrapper);
            LoginDataBase loginDataBase = new LoginDataBase();
            if (Objects.isNull(user)) {
                loginDataBase.setStatus(0);
                stringRedisTemplate.opsForValue().set("openId:" + state,JSONObject.toJSONString(loginDataBase),30, TimeUnit.MINUTES);
            }
            String subject = user.getId() + "-" + user.getUsername();
            String token = JwtUtil.createJWT(subject);
            //用户信息 权限信息 角色名称等存入redis
            loginDataBase.setUser(user);
            if ("admin".equals(user.getUsername())) {
                loginDataBase.setMenuList(sysMenuMapper.selectList(null));
            } else {
                loginDataBase.setMenuList(sysUserMapper.selectMenuBuUserId(user.getId()));
            }
            loginDataBase.setRoleNameList(sysUserMapper.selectRoleNameByUserId(user.getId()));
            loginDataBase.setStatus(1);
            stringRedisTemplate.opsForValue().set("openId:" + state, token,30,TimeUnit.MINUTES);
            stringRedisTemplate.opsForValue().set("login:token:" + token, JSONObject.toJSONString(loginDataBase),30,TimeUnit.MINUTES);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        if(userInfo == null) { //数据库不存在微信信息   客户端第一次登陆时添加信息
//            //第三步 拿着openid  和  access_token请求微信地址，得到扫描人信息
//            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
//                    "?access_token=%s" +
//                    "&openid=%s";
//            String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);
//            String resultInfo = HttpClientUtils.get(userInfoUrl);
//            System.out.println("resultInfo:"+resultInfo);
//            JSONObject resultUserInfoJson = JSONObject.parseObject(resultInfo);
//            //解析用户信息
//            //用户昵称
//            String nickname = resultUserInfoJson.getString("nickname");
//            //用户头像
//            String headimgurl = resultUserInfoJson.getString("headimgurl");
//            //获取扫描人信息添加数据库
//            userInfo = new UserInfo();
//            userInfo.setNickName(nickname);
//            userInfo.setOpenid(openid);
//            userInfo.setStatus(1);
//            userInfoService.save(userInfo);
//        }
    }

    @Override
    public Map<String, Object> getStatus(String state) {
        String token = stringRedisTemplate.opsForValue().get("openId:" + state);
        String dataLogin = stringRedisTemplate.opsForValue().get("login:token:" + token);
        LoginDataBase loginDataBase = JSONObject.parseObject(dataLogin, LoginDataBase.class);
        Map<String, Object> resultMap = new HashMap<>();
        if (Objects.isNull(loginDataBase) || loginDataBase.getStatus() == 0) {
            return resultMap;
        }
        //获取路由地址
        List<SysMenu> sysMenuList = loginDataBase.getMenuList();
        List<SysMenu> buildTree = MenuHelper.buildTree(sysMenuList);
        List<RouterVo> routerVoList = RouterHelper.buildRouters(buildTree);
        //获取按钮权限
        List<String> buttonList = sysMenuList.stream().filter(v -> v.getType() == 2).map(SysMenu::getPerms).collect(Collectors.toList());
        //获取用户信息
        SysUser user = loginDataBase.getUser();
        //获取角色名称
        List<String> roleNameList = loginDataBase.getRoleNameList();
        resultMap.put("name",user.getName());
        resultMap.put("avatar",user.getHeadUrl());
        resultMap.put("roles",JSONObject.toJSON(roleNameList));
        resultMap.put("routers",routerVoList);
        resultMap.put("buttons",buttonList);
        resultMap.put("status",1);
        resultMap.put("token",token);
        return resultMap;
    }
}
